/* Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#ifndef __MSG_TRANSFER_H__
#define __MSG_TRANSFER_H__

#include "common.h"
#include "spdm_command_impl.h"
#include "luafilter/l_callbacks.h"

extern "C" {
#include "library/spdm_common_lib.h"
}

#define TRANSPORT_TYPE_NONE 0X00
#define TRANSPORT_TYPE_MCTP 0X01
#define TRANSPORT_TYPE_TCP  0X02

#define MAX_SPDM_MSG_SIZE           0x1200
#define TRANSPORT_HEADER_SIZE       64
#define TRANSPORT_TAIL_SIZE         64
#define TRANSPORT_ADDITIONAL_SIZE   (TRANSPORT_HEADER_SIZE + TRANSPORT_TAIL_SIZE)
#define SENDER_DATA_TRANSFER_SIZE   0X1100
#define RECEIVER_DATA_TRANSFER_SIZE 0x1200
#define SENDER_BUFFER_SIZE          (TRANSPORT_ADDITIONAL_SIZE + SENDER_DATA_TRANSFER_SIZE)
#define RECEIVER_BUFFER_SIZE        (TRANSPORT_ADDITIONAL_SIZE + RECEIVER_DATA_TRANSFER_SIZE)

#if (SENDER_BUFFER_SIZE > RECEIVER_BUFFER_SIZE)
#define SENDER_RECEIVER_MAX_BUFFER_SIZE SENDER_BUFFER_SIZE
#else
#define SENDER_RECEIVER_MAX_BUFFER_SIZE RECEIVER_BUFFER_SIZE
#endif

class MsgTransfer
{
public:
    MsgTransfer(const string& device_name) : device_name(device_name) {};
    virtual ~MsgTransfer() {
        if (scratchBuffer != nullptr) {
            free(scratchBuffer);
            scratchBuffer = nullptr;
        }
    };

    string device_name;

    uint8_t sendReceiveBuffer[SENDER_RECEIVER_MAX_BUFFER_SIZE] = {};
    bool sendReceiveBufferAcquired = false;
    void *scratchBuffer = nullptr;

    uint8_t sendRecvTempBuffer[SENDER_RECEIVER_MAX_BUFFER_SIZE] = {};
    size_t  endRecvTempBufferLen = 0;

    virtual uint32_t EncodeMessage(void *spdm_context, const uint32_t *session_id, bool is_app_message,
        bool is_request_message, size_t message_size, void *message, size_t *transport_message_size,
        void **transport_message) = 0;
    virtual uint32_t DecodeMessage(void *spdm_context, uint32_t **session_id, bool *is_app_message,
        bool is_request_message, size_t transport_message_size, void *transport_message, size_t *message_size,
        void **message) = 0;
    virtual uint32_t DeviceSendMessage(void *spdm_context, size_t message_size, const void *message,
        uint64_t timeout) = 0;
    virtual uint32_t DeviceReceiveMessage(void *spdm_context, size_t *message_size, void **message,
        uint64_t timeout) = 0;
    virtual uint32_t AcquireSenderBuffer(void *spdm_context, void **msg_buf_ptr) = 0;
    virtual void ReleaseSenderBuffer(void *spdm_context, const void *msg_buf_ptr) = 0;
    virtual uint32_t AcquireReceiverBuffer(void *spdm_context, void **msg_buf_ptr) = 0;
    virtual void ReleaseReceiverBuffer(void *spdm_context, const void *msg_buf_ptr) = 0;

    virtual int32_t RegisterFunctions(void *spdm_context) = 0;
};

#endif // __MSG_TRANSFER_H__